//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<DxHelpers.h>
///	@path	~/src/graphics/
///	@date	2007/12/16
///	@desc	Some helper function for DirectX.

#pragma once

#include "xeres.h"

#include "lib/utilities/string.h"

#include <D3D9types.h>
#include <dxgi.h>

enum D3D10_PRIMITIVE_TOPOLOGY;

namespace xeres {

	/// \brief	Convert color for different color format.
	inline int d3d_convert_color( int c )
	{
		// no matter which way, we just swap R & B.
		const int cb = (c << 16) & 0x00ff0000;
		const int cr = (c >> 16) & 0x000000ff;
		return cb | cr | ( c & 0xff00ff00 );
	}

	/// \brief	Select if color needs to convert.
	inline int d3d_select_color( int c , bool sel )
	{
		return sel ? d3d_convert_color( c ) : c;
	}

	/*! 
		\struct	DXFormat
		\brief	Encapsulates 2 types together.
	*/
	struct DXFormat
	{
		D3DFORMAT		d3dfmt;
		DXGI_FORMAT		dxgifmt;

		/// \ctor
		DXFormat( void ) : d3dfmt( D3DFMT_FORCE_DWORD ) , dxgifmt( DXGI_FORMAT_FORCE_UINT ) {}

		/// \ctor
		DXFormat( const DXFormat& rhs ) : d3dfmt( rhs.d3dfmt ) , dxgifmt( rhs.dxgifmt ) {}

		/// \ctor
		DXFormat( D3DFORMAT fmt ) : d3dfmt( fmt ) , dxgifmt( DXGI_FORMAT_FORCE_UINT ) {}

		/// \ctor
		DXFormat( DXGI_FORMAT fmt ) : dxgifmt( fmt ) , d3dfmt( D3DFMT_FORCE_DWORD ) {}
	};

	/// \brief	Convert DXGI format type to HLSL type.
	const char * dxgi_to_hlsl_type( DXGI_FORMAT format );

	/// \brief	Convert D3D vertex type to HLSL type.
	const char * d3d_vertex_to_hlsl_type( D3DDECLTYPE type );

	/// \brief	Convert D3D vertex usage to HLSL semantic.
	const char * d3d_usage_to_semantic( D3DDECLUSAGE usage , int index );

	/*!
		\brief		Translate D3D device type to string.
	*/
	const WString& d3d_devtype_to_string( D3DDEVTYPE type );

	/*!
		\brief		Translate D3D 10 driver type to string.
	*/
	const WString& d3d10_drvtype_to_string( enum D3D10_DRIVER_TYPE type );

	/*!
		\brief		Translate D3D format to string.
	*/
	const WString& d3d_format_to_string( D3DFORMAT format );

	/*!
		\brief		Translate DXGI format to string.
	*/
	const WString& dxgi_format_to_string( DXGI_FORMAT format );

	/*!
		\brief		Get depth format bits.
	*/
	DWORD d3d_get_depth_bits( D3DFORMAT fmt );

	/*!
		\brief		Get stencil format bits.
	*/
	DWORD d3d_get_stencil_bits( D3DFORMAT fmt );

	/*!
		\brief		Get color channel format bits.
	*/
	DWORD d3d_get_color_bits( D3DFORMAT fmt );

	/*!
		\brief		Get color channel format bits (for dxgi).
	*/
	DWORD dxgi_get_color_bits( DXGI_FORMAT fmt );

	/*!
		\brief		Get color channel format bits.
	*/
	DWORD d3d_get_color_size( D3DFORMAT fmt );

	/*!
		\brief		Get color channel format bits (for dxgi).
	*/
	DWORD dxgi_get_color_size( DXGI_FORMAT fmt );

	/*!
		\brief		Translate error code to string.
	*/
	const wchar_t * d3d_get_err( HRESULT result );

	/*!
		\brief		Convert geometry type to DX9 type.
	*/
	D3DPRIMITIVETYPE d3d_topology_type9( enum TopologyType type );

	/*!
		\brief		Convert geometry type to DX10 type.
	*/
	D3D10_PRIMITIVE_TOPOLOGY d3d_topology_type10( enum TopologyType type );

	/*! 
		\brief		Get primitive count.
	*/
	size_t d3d_prim_count( enum TopologyType type , size_t vertex_count , size_t index_count );

} // namespace xeres
